Skip to content

Comments

Trusted senders#618

Merged
nizzyabi merged 8 commits intoMail-0:stagingfrom
danteissaias:staging
Apr 9, 2025
Merged

Trusted senders#618
nizzyabi merged 8 commits intoMail-0:stagingfrom
danteissaias:staging

Conversation

@danteissaias
Copy link
Contributor

@danteissaias danteissaias commented Apr 7, 2025

Description

  • Add a "trust sender" button to let you enable external images from a specific sender.
  • Include a section in the settings page to manage trusted senders (this section stays hidden if you don’t have any trusted senders).
  • Improve settings typesafety. Use the zod schema as the source of truth for settings type, and default settings should meet that zod schema.

Type of Change

Please delete options that are not relevant.

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature with breaking changes)
  • 📝 Documentation update
  • 🎨 UI/UX improvement
  • 🔒 Security enhancement
  • ⚡ Performance improvement

Areas Affected

Please check all that apply:

  • Email Integration (Gmail, IMAP, etc.)
  • User Interface/Experience
  • Authentication/Authorization
  • Data Storage/Management
  • API Endpoints
  • Documentation
  • Testing Infrastructure
  • Development Workflow
  • Deployment/Infrastructure

Testing Done

Describe the tests you've done:

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • Cross-browser testing (if UI changes)
  • Mobile responsiveness verified (if UI changes)

Security Considerations

For changes involving data or authentication:

  • No sensitive data is exposed
  • Authentication checks are in place
  • Input validation is implemented
  • Rate limiting is considered (if applicable)

Checklist

  • I have read the CONTRIBUTING document
  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in complex areas
  • I have updated the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix/feature works
  • All tests pass locally
  • Any dependent changes are merged and published

Additional Notes

N/A

Screenshots/Recordings

Screenshot 2025-04-07 at 21 26 55 Screenshot 2025-04-07 at 21 22 49

By submitting this pull request, I confirm that my contribution is made under the terms of the project's license.

Summary by CodeRabbit

  • New Features

    • Added a trusted senders management option on the settings page to add and remove approved email senders.
    • Introduced a trust action directly within the email view, allowing users to enable images for specific senders.
    • Enhanced email display by providing sender context for improved rendering.
    • Updated user prompts and tooltips with clear labels for trusting and removing senders.
  • Bug Fixes

    • Resolved issues related to saving user settings for trusted senders.

@vercel
Copy link

vercel bot commented Apr 7, 2025

@danteissaias is attempting to deploy a commit to the Zero Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 7, 2025

Walkthrough

The pull request introduces functionality for managing trusted senders within the email application. It adds a new form field in the settings page for handling a list of trusted sender emails, updates the MailIframe component to accept the sender's email, and integrates a trust action that updates user settings. Additionally, it adjusts localization files to include new text entries and updates the database schema for user settings to accommodate the new trustedSenders field.

Changes

Files Summary
apps/mail/.../settings/general/page.tsx Added new trustedSenders field to the form schema with updated default values; introduced a FormField component with email removal feature.
apps/mail/components/mail/mail-display.tsx
apps/mail/components/mail/mail-iframe.tsx
Modified MailIframe to add a senderEmail prop; implemented new trust sender functionality with an async action and UI button for trusting senders.
apps/mail/locales/en.json Introduced new localization entries: "trustSender", "remove", "trustedSenders", and "trustedSendersDescription".
packages/db/.../user_settings_default.ts Updated user settings schema to include the trustedSenders property with an empty array as default; adjusted type definitions accordingly.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant MI as MailIframe
    participant S as Server/API

    U->>MI: Click "Trust Sender" button
    MI->>S: Invoke onTrustSender(senderEmail)
    S-->>MI: Return success or failure
    alt Success
        MI->>U: Update UI (enable images for trusted sender)
    else Failure
        MI->>U: Display error toast
    end
Loading

Possibly related PRs

  • Feature/persist user settings #403: The changes in the main PR are related to those in the retrieved PR as both involve the introduction and management of the trustedSenders property within user settings, with the main PR focusing on its implementation in the UI and the retrieved PR addressing its persistence in the backend.

Suggested reviewers

  • nizzyabi

Poem

I'm a little rabbit, hopping with glee,
Trusted senders now set my email free.
With button clicks and schema so neat,
My inbox is hopping to a fresh new beat.
Carrots and code, oh what a treat!
🐰✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6ca49d and 6423e14.

📒 Files selected for processing (1)
  • apps/mail/app/(routes)/settings/general/page.tsx (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/mail/app/(routes)/settings/general/page.tsx

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
apps/mail/components/mail/mail-iframe.tsx (1)

101-106: Consider conditionally rendering the Trust Sender button.

The "Trust Sender" button is currently always shown when images are hidden, even if the sender is already trusted. Consider conditionally rendering this button only when the sender is not already trusted.

- <button
-   onClick={() => void onTrustSender(senderEmail)}
-   className="ml-2 cursor-pointer underline"
- >
-   {t('common.actions.trustSender')}
- </button>
+ {!isTrustedSender && (
+   <button
+     onClick={() => void onTrustSender(senderEmail)}
+     className="ml-2 cursor-pointer underline"
+   >
+     {t('common.actions.trustSender')}
+   </button>
+ )}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b612d4a and a528b08.

📒 Files selected for processing (5)
  • apps/mail/app/(routes)/settings/general/page.tsx (4 hunks)
  • apps/mail/components/mail/mail-display.tsx (1 hunks)
  • apps/mail/components/mail/mail-iframe.tsx (2 hunks)
  • apps/mail/locales/en.json (2 hunks)
  • packages/db/src/user_settings_default.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (2)
apps/mail/components/mail/mail-iframe.tsx (4)
apps/mail/hooks/use-settings.ts (1)
  • useSettings (7-38)
packages/db/src/user_settings_default.ts (1)
  • defaultUserSettings (3-10)
apps/mail/lib/timezones.ts (1)
  • getBrowserTimezone (1-1)
apps/mail/actions/settings.ts (1)
  • saveUserSettings (53-88)
apps/mail/app/(routes)/settings/general/page.tsx (2)
apps/mail/components/ui/form.tsx (4)
  • FormField (169-169)
  • FormItem (164-164)
  • FormLabel (165-165)
  • FormDescription (167-167)
apps/mail/components/ui/tooltip.tsx (3)
  • Tooltip (59-59)
  • TooltipTrigger (59-59)
  • TooltipContent (59-59)
🪛 Biome (1.9.4)
apps/mail/app/(routes)/settings/general/page.tsx

[error] 279-279: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

🔇 Additional comments (12)
apps/mail/components/mail/mail-display.tsx (1)

371-371: Successfully implemented sender email prop to MailIframe.

The addition of the senderEmail prop to the MailIframe component enables the trusted sender functionality, allowing the component to determine if the current sender is in the user's trusted list.

packages/db/src/user_settings_default.ts (3)

9-10: Good addition of trustedSenders field to default settings.

The empty array initialization is appropriate as users start with no trusted senders.


18-18: Well-defined schema for trustedSenders.

Using z.string().array() properly defines the expected data type for validation.


21-21: Improved type safety by deriving from schema.

Changing from typeof defaultUserSettings to z.infer<typeof userSettingsSchema> ensures that the types are derived from the validation schema, making the system more robust against mismatches.

apps/mail/app/(routes)/settings/general/page.tsx (3)

45-45: Good schema definition for trustedSenders.

The schema correctly defines trusted senders as an array of strings.


140-140: Appropriate default initialization.

Initializing trustedSenders as an empty array aligns with the default settings.


279-296: Well-implemented sender removal functionality.

The remove button with tooltip provides a good user experience for managing trusted senders. The implementation correctly filters out the removed sender from the array.

🧰 Tools
🪛 Biome (1.9.4)

[error] 279-279: Missing key property for this element in iterable.

The order of the items may change, and having a key can help React identify which item was moved.
Check the React documentation.

(lint/correctness/useJsxKeyInIterable)

apps/mail/locales/en.json (3)

37-37: Good addition of 'Trust Sender' translation.

This translation entry supports the new button in the mail interface.


40-40: Added 'Remove' translation for UI consistency.

This translation will be used for the remove button in the trusted senders list.


308-309: Clear and descriptive translations for trusted senders section.

These translations effectively communicate the purpose of the trusted senders feature to the user.

apps/mail/components/mail/mail-iframe.tsx (2)

12-17: Well implemented parameter addition for tracking trusted senders.

The added senderEmail parameter and the logic to check if a sender is trusted are well implemented. The code correctly initializes the imagesEnabled state based on whether the sender is trusted or external images are globally enabled.


2-10: Proper organization of imports.

The imports have been well organized, with appropriate separation of internal and external dependencies.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
apps/mail/components/mail/mail-iframe.tsx (2)

22-42: Prevent duplicate entries in trustedSenders array

The current implementation doesn't check if the sender is already in the trusted list before adding it, which could lead to duplicate entries.

const onTrustSender = useCallback(async (senderEmail: string) => {
  setImagesEnabled(true);

  const existingSettings = settings ?? {
    ...defaultUserSettings,
    timezone: getBrowserTimezone(),
  };

  const { success } = await saveUserSettings({
    ...existingSettings,
    trustedSenders: settings?.trustedSenders
-      ? settings.trustedSenders.concat(senderEmail)
+      ? settings.trustedSenders.includes(senderEmail)
+        ? settings.trustedSenders
+        : settings.trustedSenders.concat(senderEmail)
      : [senderEmail],
  });

  if (!success) {
    toast.error('Failed to trust sender');
  } else {
    mutate();
  }
}, [settings, mutate]);

12-17: 🛠️ Refactor suggestion

Consider validating senderEmail for edge cases

Since senderEmail is now a required prop and used in critical checks, you should add validation to handle edge cases like empty strings or undefined values.

export function MailIframe({ html, senderEmail }: { html: string; senderEmail: string }) {
+  const validSenderEmail = senderEmail?.trim() || '';
  const { settings, mutate } = useSettings();
-  const isTrustedSender = settings?.trustedSenders?.includes(senderEmail);
+  const isTrustedSender = settings?.trustedSenders?.includes(validSenderEmail);
  const [imagesEnabled, setImagesEnabled] = useState(
    isTrustedSender || settings?.externalImages || false,
  );
🧹 Nitpick comments (3)
apps/mail/components/mail/mail-iframe.tsx (3)

101-106: Hide or disable the trust button for already trusted senders

The "Trust Sender" button is always visible, even if the sender is already in the trusted senders list. This could confuse users who might try to trust a sender multiple times.

{!imagesEnabled && !settings?.externalImages && (
  <div className="flex items-center justify-start bg-amber-500 p-2 text-sm text-amber-900">
    <p>{t('common.actions.hiddenImagesWarning')}</p>
    <button
      onClick={() => setImagesEnabled(!imagesEnabled)}
      className="ml-2 cursor-pointer underline"
    >
      {imagesEnabled ? t('common.actions.disableImages') : t('common.actions.showImages')}
    </button>
+    {!isTrustedSender && (
      <button
        onClick={() => onTrustSender(senderEmail)}
        className="ml-2 cursor-pointer underline"
      >
        {t('common.actions.trustSender')}
      </button>
+    )}
  </div>
)}

37-41: Improve error handling for saveUserSettings

The current error handling only shows a toast message. Consider adding more robust error handling to provide a better user experience, especially for network failures.

if (!success) {
  toast.error('Failed to trust sender');
+  // Revert UI state since operation failed
+  setImagesEnabled(settings?.externalImages || false);
} else {
  mutate();
+  toast.success(t('common.actions.senderTrusted'));
}

30-35: Add a helper function for managing trusted senders

The logic for updating the trusted senders array could be extracted into a reusable helper function for better maintainability and to ensure consistent behavior across the application.

+// Add this helper function at the top of the file or in a separate utility file
+const addTrustedSender = (currentList: string[] = [], newSender: string): string[] => {
+  if (!newSender || currentList.includes(newSender)) {
+    return currentList;
+  }
+  return [...currentList, newSender];
+};

// Then in the component
const { success } = await saveUserSettings({
  ...existingSettings,
-  trustedSenders: settings?.trustedSenders
-    ? settings.trustedSenders.concat(senderEmail)
-    : [senderEmail],
+  trustedSenders: addTrustedSender(settings?.trustedSenders, senderEmail),
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1335fd0 and f09b2a4.

📒 Files selected for processing (1)
  • apps/mail/components/mail/mail-iframe.tsx (2 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
apps/mail/components/mail/mail-iframe.tsx (4)
apps/mail/hooks/use-settings.ts (1)
  • useSettings (7-38)
packages/db/src/user_settings_default.ts (1)
  • defaultUserSettings (3-10)
apps/mail/lib/timezones.ts (1)
  • getBrowserTimezone (1-1)
apps/mail/actions/settings.ts (1)
  • saveUserSettings (53-88)

@SwedishChef1
Copy link

@danteissaias - I think we discussed in discord, but you are also doing these two yea?

  1. ensuring that the banner only shows for emails with images
  2. update bg or text colour for better accessibility (black text or lighter bg).

@danteissaias
Copy link
Contributor Author

@danteissaias - I think we discussed in discord, but you are also doing these two yea?

  1. ensuring that the banner only shows for emails with images
  2. update bg or text colour for better accessibility (black text or lighter bg).

Yeah, I'll take a look at doing these in follow-up PRs.

@nizzyabi
Copy link
Collaborator

nizzyabi commented Apr 7, 2025

love this. lets make the area a Scroll Area so that when there are more than 5-6 we can scroll and see more

@danteissaias
Copy link
Contributor Author

Pushed a couple changes:

  • List is now a scroll area with a max-height of 5/6 entries
  • List is now hidden in settings if "display external images" is enabled

@nizzyabi nizzyabi merged commit 4997303 into Mail-0:staging Apr 9, 2025
2 of 3 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Apr 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants